<template>
  <div class="web_socket" :class="{is_show: isHide}" v-loading="isLoading">
    <div class="info_header">
      <span :class="{active: tabToggle===1}" @click="changeMessageTabs(1)">待办任务</span>
      <span :class="{active: tabToggle===2}" @click="changeMessageTabs(2)">系统通知</span>
    </div>
    <div class="info_cont" v-if="tabToggle===1">
      <div class="info_content" v-for="(item, index) in taskMessage" :key="index">
        <p :class="{has_url: item.pageUrl}" @click="skipPage(item)">
          <i :class="{read_icon: item.statusValue !== 'Unread'}"></i>
          {{item.content}}
        </p>
        <span>{{item.createDate}}</span>
        <p class="copy_btn" @click="copyNumber(item.workorderOrTurnoverNumber, $event)">复制ID</p>
      </div>
      <div class="message_empty" v-if="!taskMessage.length">
        <img src="@/assets/img/message_empty.png" alt="">
        <span>暂无待办任务</span>
      </div>
    </div>
    <div class="info_cont" v-if="tabToggle===2">
      <div class="info_content" v-for="(item, index) in sysMessages" :key="index">
        <p :class="{has_url: item.pageUrl}">
          <i :class="{read_icon: item.statusValue !== 'Unread'}"></i>
          {{item.content}}
        </p>
        <span>{{item.createDate}}</span>
      </div>
      <div class="message_empty" v-if="!sysMessages.length">
        <img src="@/assets/img/message_empty.png" alt="">
        <span>暂无系统通知</span>
      </div>
    </div>
    <div class="info_footer" @click="skipPage({pageUrl: 'message'})">
      查看全部
    </div>
    <div class="unfold_btn" @click="isHide = !isHide" v-if="!isHide">
      <i class="iconfont icon-arrow_zhankai"></i>
    </div>
  </div>
</template>

<script>
import clip from '@/utils/clipboard'

export default {
  name: 'WebSocket',
  data() {
    return {
      isHide: true, // 消息栏显示/隐藏
      linkTimes: 0, // 登录次数
      connectAccount: 0, // 连接次数
      timer: '', // 保持连接计时器
      tabToggle: 1, // tab索引
      messageList: {}, // 消息栏列表数据
      sysMessages: [], // 系统消息
      taskMessage: [], // 待办任务
      isLoading: false, // 是否加载
      sockets: {}, // socket集合
    }
  },
  computed: {
    userName() {
      return this.$store.state.userInfo.userName || ''
    },
    socketServerIP1() {
      return this.$store.state.userInfo.socketServerIP || ''
    },
    socketServerIP2() {
      return this.$store.state.userInfo.socketServerIP2 || ''
    },
    socketServerPort() {
      return this.$store.state.userInfo.socketServerPort || ''
    },
    websocketUrl() {
      if (this.socketServerPort) {
        return [
          {url: `ws://${this.socketServerIP1}:${this.socketServerPort}/websocket/socketServer.do`, key: this.socketServerIP1},
          {url: `ws://${this.socketServerIP2}:${this.socketServerPort}/websocket/socketServer.do`, key: this.socketServerIP2},
        ]
      } else {
        return []
      }
    }
  },
  mounted() {
    this._login()
    this.getUnreadNumber()
    this.getMessageList()
  },
  beforeDestroy() {
    // 断开socket
    this.cancelSocket()
  },
  watch: {
    userName: {
      handler() {
        if (this.userName) {
          this.cancelSocket()
          this._login()
        }
      },
      deep: true
    }
  },
  methods: {
    // 打开弹窗
    openMessage() {
      this.tabToggle = 1
      this.isHide = !this.isHide
      if (!this.isHide && !this.isLoading) {
        this.getUnreadNumber()
        this.getMessageList()
      } else {
        this.sysMessages = []
      }
    },
    // 注册webScoket 用户表
    _login() {
      if (!this.userName) return
      this.linkTimes = this.linkTimes + 1
      this.$store.dispatch('saveData', {
        method: 'get',
        url: 'a/webmessage/webMessage/login?username=' + this.userName,
        noCommit: true
      }).then(() => {
        this.connections()
        this.linkTimes = 0
      }).catch(() => {
        if (this.linkTimes >= 5) {
          this.tipMessage('error', '消息连接出现异常，请刷新页面进行重连', 3000)
        } else {
          this._login()
        }
      })
    },
    // 多服务sockets连接
    connections() {
      this.connectAccount++
      if (this.connectAccount >= 5) return
      if (Array.isArray(this.websocketUrl) && this.websocketUrl.length) {
        this.websocketUrl.forEach((item) => {
          let name = `socket${item.key}`
          if (this.sockets[name] && this.sockets[name].url) return
          this.sockets[name] = new WebSocket(item.url)
          // 连接成功回调
          this.sockets[name].onopen = () => {
            if (this.sockets[name].readyState === this.sockets[name].OPEN) {
              if (this.sockets[name]) this.sockets[name].send(this.userName)
              setInterval(() => {
                if (this.sockets[name]) this.sockets[name].send(this.userName)
              }, 60000)
            }
          }
          // 接收后台消息
          this.sockets[name].onmessage = (e) => {
            if (e.data) {
              const message = JSON.parse(e.data)
              if (message.to && message.to === this.userName) {
                this.popMessage(message.type, message.content)
              }
            }
            this.getUnreadNumber()
            this.getMessageList()
          }
          // 连接发生错误
          this.sockets[name].onerror = () => {
            this.sockets[name].close()
            /*this.sockets[name] = null
            this._login()*/
          }
          // 连接关闭
          this.sockets[name].onclose = () => {
            this.sockets[name] = null
            this._login()
          }
        })
      }
    },
    // 销毁socket
    cancelSocket() {
      for (let socket in this.sockets) {
        if (this.sockets[socket]) {
          this.sockets[socket].close()
          this.sockets[socket] = null
        }
      }
    },
    // 消息提示
    popMessage(title, str) {
      this.$notify({
        title: title,
        message: str,
        iconClass: 'self_message_icon iconfont icon-tishi1',
        duration: 3000
      })
    },
    // 切换消息列表
    changeMessageTabs(value) {
      this.tabToggle = value
      this.sysMessageAutoRead(this.sysMessages)
    },
    // 获取全量未读消息数量
    getUnreadNumber() {
      this.$store.dispatch('saveData', {
        method: 'get',
        url: 'a/webmessage/webMessage/getunreadmessage',
        noCommit: true
      }).then((res) => {
        if (res.data !== undefined) {
          this.$store.commit('SetUnreadNumber', res.data)
        }
        // this.getMessageList()
      })
    },
    // 获取消息栏列表数据
    getMessageList() {
      this.isLoading = true
      this.$store.dispatch('saveData', {
        method: 'get',
        url: 'a/webmessage/webMessage/getrecentmessage',
        noCommit: true
      }).then((res) => {
        this.taskMessage = res.data.taskMessage
        this.sysMessages = res.data.sysMessages
      }).finally(() => {
        this.isLoading = false
      })
    },
    // 点击消息跳转页面
    skipPage(item) {
      if (item) {
        if (item.statusValue === 'Unread') {
          let obj = {
            id: item.id,
            createDate: item.createDate
          }
          this.readRequest([obj])
        }
        if (item.pageUrl) {
          this.$router.push(item.pageUrl)
        }
        this.isHide = true
        this.sysMessages = []
      }
    },
    // 系统自动标记已读
    sysMessageAutoRead(list) {
      let postData = []
      list.forEach((item) => {
        if (item.statusValue === 'Unread') {
          postData.push({id: item.id, createDate: item.createDate})
        }
      })
      this.readRequest(postData)
    },
    /**
     * 标记已读请求
     * @param postData 被标记的数据
     */
    readRequest(postData) {
      if (postData.length) {
        this.$store.dispatch('saveData', {
          method: 'post',
          url: 'a/webmessage/webMessage/changestatus',
          data: {list: postData},
          noCommit: true
        }).then(() => {
          this.getMessageList()
          this.getUnreadNumber()
        })
      }
    },
    // 复制编码
    copyNumber(value, event) {
      clip(value, event)
      this.tipMessage('success', 'ID已复制')
    },
    /**
     * 提示
     * @param type 提示类型
     * @param str 提示内容
     * @param duration 提示时间
     */
    tipMessage(type, str, duration) {
      this.$message({
        type: type,
        message: str,
        duration: duration || 1500,
        center: true
      })
    }
  },
}
</script>

<style scoped lang="less">
  .web_socket {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    width: 400px;
    height: 100%;
    background-color: #fff;
    border-left: @mesBorDefault;
    transition: all .3s;
    z-index: 999;
    padding: 15px;
    box-sizing: border-box;
    padding-bottom: 60px;

    &.is_show {
      right: -400px
    }

    .info_header {
      height: 40px;
      background-color: #ffffff;
      border-radius: 2px;
      text-align: center;
      display: flex;
      align-items: center;
      font-size: 16px;
      cursor: pointer;
      margin-bottom: 2px;

      span {
        display: block;
        line-height: 40px;
        color: #7e8e9f;
        width: 50%;
        border: solid 1px #dcdfe6;
        user-select: none;
        transition: all 0.1s ease-in;

        &:first-child {
          border-right: none;
        }

        &.active {
          background-color: #00b4ff;
          color: #fff;
          border-color: #00b4ff;
        }
      }
    }

    .info_cont {
      width: 100%;
      height: calc(100% - 42px);
      overflow: auto;

      &::-webkit-scrollbar {
        /*滚动条*/
        width: 17px;
        height: 17px;
        cursor: pointer;
        margin-left: 4px;
      }

      &::-webkit-scrollbar-thumb {
        /*小方块*/
        border-radius: 16px;
        box-shadow: @mesTableScrollThumbShow;
        background: @mesTableScrollThumbBg;
        cursor: pointer;
        border: @mesTableScrollThumbBorder;
      }

      &::-webkit-scrollbar-thumb:hover {
        cursor: pointer;
      }

      &::-webkit-scrollbar-track {
        /*轨道*/
        width: 17px;
        background: @mesTableScrollTrackBg;
      }

      &::-webkit-scrollbar-track:hover {
        cursor: pointer;
      }

      .info_content {
        padding: 15px 15px 10px 15px;
        position: relative;
        border-bottom: solid 1px #eeeeee;

        &:hover .copy_btn {
          display: block;
        }

        i {
          display: inline-block;
          width: 8px;
          height: 8px;
          background-color: #f8000f;
          border-radius: 50%;
          position: absolute;
          top: 20px;
          left: 0;

          &.read_icon {
            background-color: #fff !important;
          }
        }

        p {
          color: #333333;
          font-size: 14px;

          &.has_url {
            cursor: pointer;
          }

          &.has_url:hover {
            color: #0066cc;
          }
        }

        span {
          color: #999;
          font-size: 12px;
        }

        .copy_btn {
          line-height: 20px;
          width: 58px;
          text-align: center;
          color: #0066cc;
          position: absolute;
          right: 14px;
          bottom: 7px;
          background-color: rgba(33, 150, 243, 0.15);
          border-radius: 1px;
          padding: 1px 2px;
          cursor: pointer;
          font-size: 12px;
          display: none;
          user-select: none !important;

          &:active {
            background-color: rgba(33, 150, 243, 0.25) !important;
          }
        }
      }

      .message_empty {
        width: 120px;
        margin: 0 auto;
        color: #a1b1c1;
        font-size: 14px;
        text-align: center;

        img {
          width: 120px;
          height: 120px;
          margin-top: 100px;
        }
      }
    }

    .info_footer {
      width: 100%;
      border-top: solid 1px #dcdfe6;
      background-color: #fff;
      line-height: 60px;
      text-align: center;
      color: #7e8e9f;
      font-size: 16px;
      cursor: pointer;
      position: absolute;
      bottom: 0;
      left: 0;
    }

    .unfold_btn {
      color: #333;
      cursor: pointer;
      position: absolute;
      width: 16px;
      height: 50px;
      line-height: 50px;
      left: -17px;
      top: 0;
      bottom: 0;
      margin: auto;
      background-color: #fff;
      border: @mesBorDefault;
      border-right: none;
      border-radius: 4px 0 0 4px;
      box-sizing: border-box;
    }
  }
</style>
<style>
  .self_message_icon {
    color: #f8000f;
  }
</style>
